package tests.pl.shenlon.poker.game.gametypes;

import junit.framework.Assert;

import org.junit.Before;
import org.junit.Test;

import pl.shenlon.poker.game.PlayerActionType;
import pl.shenlon.poker.game.PokerPlayer;
import pl.shenlon.poker.game.gametypes.FixedLimitPokerGame;
import pl.shenlon.poker.game.gametypes.PokerGame;

public class FixedLimitPokerGameTest {
	private static final int CASH = 1000;

	private PokerGame game;

	private PokerPlayer playerA, playerB;

	@Before
	public void setUp() {
		game = new FixedLimitPokerGame();
	}

	@Test
	public void testPlayGame() {
		playerA = new MockPokerPlayer(CASH, PlayerActionType.FOLD, "A");
		playerB = new MockPokerPlayer(CASH, PlayerActionType.CALL, "B");
		game.setPlayerA(playerA);
		game.setPlayerB(playerB);
		
		PokerPlayer winner = game.playGame(true);
		Assert.assertEquals(playerB, winner);

		playerA = new MockPokerPlayer(CASH, PlayerActionType.CALL, "A");
		game.setPlayerA(playerA);

		winner = game.playGame(true);
		Assert.assertNotNull(winner);
		System.out.println(winner + ": " + winner.getHand() + "-"
				+ game.getTableCards());

	}

	@Test
	public void testTurnFlop() {
		playerA = new MockPokerPlayer(CASH, PlayerActionType.FOLD, "A");
		playerB = new MockPokerPlayer(CASH, PlayerActionType.CALL, "B");
		game.setPlayerA(playerA);
		game.setPlayerB(playerB);
		game.dealCards();
		game.turnFlop();
		Assert.assertEquals(playerB, game.getWinner());

		game.hideTableCards();
		game.clearWinner();

		playerA = new MockPokerPlayer(CASH, PlayerActionType.CALL, "A");
		playerB = new MockPokerPlayer(CASH, PlayerActionType.FOLD, "B");
		game.setPlayerA(playerA);
		game.setPlayerB(playerB);
		game.dealCards();
		game.turnFlop();
		Assert.assertEquals(playerA, game.getWinner());
		Assert.assertEquals(0, game.getRaiseCounter());

		game.hideTableCards();
		game.clearWinner();

		playerB = new MockPokerPlayer(CASH, PlayerActionType.RAISE, "B");
		game.setPlayerB(playerB);
		game.dealCards();
		game.turnFlop();
		Assert.assertNull(game.getWinner());
		Assert.assertEquals(4, game.getRaiseCounter());

		Assert.assertEquals(3, game.getTableCards().getVisibleCardsCount());
	}

	@Test
	public void testTurnPreFlop() {
		playerA = new MockPokerPlayer(CASH, PlayerActionType.FOLD, "A");
		playerB = new MockPokerPlayer(CASH, PlayerActionType.CALL, "B");
		game.setPlayerA(playerA);
		game.setPlayerB(playerB);

		game.dealCards();
		game.turnPreFlop();
		Assert.assertEquals(playerB, game.getWinner());

		game.setPlayerA(playerB);
		game.setPlayerB(playerA);
		game.turnPreFlop();
		Assert.assertEquals(playerB, game.getWinner());

		playerA = new MockPokerPlayer(CASH, PlayerActionType.CHECK, "A");
		game.setPlayerA(playerA);
		game.setPlayerB(playerB);
		game.clearWinner();
		game.turnPreFlop();
		Assert.assertNull(game.getWinner());

		playerA = new MockPokerPlayer(CASH, PlayerActionType.RAISE, "A");
		game.setPlayerA(playerA);
		game.clearWinner();
		game.turnPreFlop();
		Assert.assertNull(game.getWinner());
		Assert.assertEquals(4, game.getRaiseCounter());

		Assert.assertEquals(0, game.getTableCards().getVisibleCardsCount());
	}

	@Test
	public void testTurnRiver() {
		playerA = new MockPokerPlayer(CASH, PlayerActionType.FOLD, "A");
		playerB = new MockPokerPlayer(CASH, PlayerActionType.CALL, "B");
		game.setPlayerA(playerA);
		game.setPlayerB(playerB);
		game.dealCards();
		game.turnRiver();
		Assert.assertEquals(playerB, game.getWinner());

		game.hideTableCards();
		game.clearWinner();

		playerA = new MockPokerPlayer(CASH, PlayerActionType.CALL, "A");
		playerB = new MockPokerPlayer(CASH, PlayerActionType.FOLD, "B");
		game.setPlayerA(playerA);
		game.setPlayerB(playerB);
		game.dealCards();
		game.turnRiver();
		Assert.assertEquals(playerA, game.getWinner());
		Assert.assertEquals(0, game.getRaiseCounter());

		game.hideTableCards();
		game.clearWinner();

		playerB = new MockPokerPlayer(CASH, PlayerActionType.RAISE, "B");
		game.setPlayerB(playerB);
		game.dealCards();
		game.turnRiver();
		Assert.assertNull(game.getWinner());
		Assert.assertEquals(4, game.getRaiseCounter());

		Assert.assertEquals(1, game.getTableCards().getVisibleCardsCount());
	}

	@Test
	public void testTurnTurn() {
		playerA = new MockPokerPlayer(CASH, PlayerActionType.FOLD, "A");
		playerB = new MockPokerPlayer(CASH, PlayerActionType.CALL, "B");
		game.setPlayerA(playerA);
		game.setPlayerB(playerB);
		game.dealCards();
		game.turnTurn();
		Assert.assertEquals(playerB, game.getWinner());

		game.hideTableCards();
		game.clearWinner();

		playerA = new MockPokerPlayer(CASH, PlayerActionType.CALL, "A");
		playerB = new MockPokerPlayer(CASH, PlayerActionType.FOLD, "B");
		game.setPlayerA(playerA);
		game.setPlayerB(playerB);
		game.dealCards();
		game.turnTurn();
		Assert.assertEquals(playerA, game.getWinner());
		Assert.assertEquals(0, game.getRaiseCounter());

		game.hideTableCards();
		game.clearWinner();

		playerB = new MockPokerPlayer(CASH, PlayerActionType.RAISE, "B");
		game.setPlayerB(playerB);
		game.dealCards();
		game.turnTurn();
		Assert.assertNull(game.getWinner());
		Assert.assertEquals(4, game.getRaiseCounter());

		Assert.assertEquals(1, game.getTableCards().getVisibleCardsCount());
	}

	@Test
	public void testNextBetSize() {
		playerA = new MockPokerPlayer(CASH, PlayerActionType.CALL, "A");
		playerB = new MockPokerPlayer(CASH, PlayerActionType.FOLD, "B");
		game.setPlayerA(playerA);
		game.setPlayerB(playerB);
		game.dealCards();
		Assert.assertEquals(game.getBetSize() + game.getBigBlind(),
				game.nextBetAmount());
		game.getTableCards().show(0, 1, 2);

		Assert.assertEquals(game.getSmallBlind() + game.getBigBlind(),
				game.nextBetAmount());
		game.getTableCards().show(3);
		Assert.assertEquals(game.getSmallBlind() + 2 * game.getBigBlind(),
				game.nextBetAmount());
		game.getTableCards().show(4);
		Assert.assertEquals(game.getSmallBlind() + 2 * game.getBigBlind(),
				game.nextBetAmount());

		game.dealCards();
		Assert.assertEquals(game.getBetSize() + game.getBigBlind(),
				game.nextBetAmount());
		game.setBetSize(game.nextBetAmount());
		Assert.assertEquals(game.getBetSize() + game.getBigBlind(),
				game.nextBetAmount());
		game.getTableCards().show(0, 1, 2);

		Assert.assertEquals(game.getBetSize() + game.getBigBlind(),
				game.nextBetAmount());
		game.getTableCards().show(3);
		Assert.assertEquals(game.getBetSize() + 2 * game.getBigBlind(),
				game.nextBetAmount());
		game.getTableCards().show(4);
		Assert.assertEquals(game.getBetSize() + 2 * game.getBigBlind(),
				game.nextBetAmount());

	}
}